package com.hfb.mashibing.alip8.juc.c020_01_interview;

import java.util.ArrayList;
import java.util.List;

/**
 * 面试题（淘宝？）
 * 实现一个容器，提供2个方法：add，size
 * 写2个线程，线程1添加10个袁术到容器中，
 * 线程2实现监控元数个数。当个数为5时线程2 提出提示并退出。
 *
 * 仔细分析下面的程序能完成任务吗?可以读到输出结果，
 * 但并不是size=5时t2退出，而是t1结束，t2才结束
 * 答：不行，（多线程）
 * 1、notify()或者notifyAll()调用时并不会真正释放对象锁,
 *      必须等到synchronized方法或者语法块执行完才真正释放锁.
 *      因此，t2直到结束才得到锁
 */
public class T03_NotifyHoldingLock {
    // volatile 使线程间可见
    volatile List lis = new ArrayList();

    public void add(Object o) {
        lis.add(o);
    }
    public int size() {
        return lis.size();
    }

    public static void main(String[] args) throws InterruptedException {
        T03_NotifyHoldingLock o = new T03_NotifyHoldingLock();
        final Object lock = new Object();

        new Thread(()->{
            synchronized (lock) {
                System.out.println("t2 启动");
                if (o.size() != 5) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("t2 结束🔚 ");
            }
        }, "t2").start();

        Thread.sleep(1000);


        new Thread(()->{
            System.out.println("t1 启动");
            synchronized (lock) {
                for (int i=0;i<10;i++) {
                    o.add(new Object());
                    System.out.println("add "+i);

                    if (o.size() == 5) {
                        lock.notify();
                    }

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println("t1 结束🔚");
        }, "t1").start();



    }
}
